import org.codehaus.groovy.grails.plugins.springsecurity.Secured
import grails.converters.JSON
import com.st.utils.DataList

// TODO: modify to allow user also.
@Secured(['ROLE_ADMIN', 'ROLE_POWER_USER'])
class OfficeCallController extends AbstractSecurity {

    def companyService
    def personService
    
    static sdf = new java.text.SimpleDateFormat("MM/dd/yyyy hh:mm")

    // the delete, save and update actions only accept POST requests
    static allowedMethods = [delete:'POST', save:'POST', update:'POST']

    /** VIEWS **/
    def index = { redirect(action:list,params:params) }

    // List Views
    def list = {
        if (params.companyId) {
            return [companyId:params.companyId]
        } else {
            flash.error = "There is no company specified for which to list the office calls for."
        }
    }

    // Show Views
    def show = {
        println "params in show = " + params
        def officeCall = OfficeCall.get(params.id)

        if (!officeCall) {
            flash.message = "Office Call not found with id ${params.id}"
            redirect action:list
        } else { 
            return [officeCall:officeCall]
        }
    }

    // Create/Edit Views
    def create = {
        if (!params.companyId) {
            redirect uri:"/"
            return
        }

        def company = Company.get(params.companyId)
        if (!company) {
            redirect uri:"/"
            return
        }

        if (company.reps?.size() == 0) {
            flash.error = "There are no reps for this company. You must add a rep to the company before creating a office visit."
        }

        if (flash.error) {
            redirect controller:params.returnController, action:params.returnAction, id:company.id
            return
        }

        def officeCall = new OfficeCall()
        officeCall.setCompany(company)
        officeCall.rep = personService.getCompanyRep(company, getUser())

        return [officeCall:officeCall, returnAction:params.returnAction, returnController:params.returnController]
    }

    def edit = {
        def officeCall = OfficeCall.get(params.id)

        if(!officeCall) {
            flash.message = "officeCall not found with id ${params.id}"
            redirect(action:list)
        }
        else {
            return [officeCall:officeCall]
        }
    }

//    def editList = {
//        println "officeCalls edit list = " + params
//        def company = Company.get(params.companyId)
//        if(!company) {
//            flash.message = "Company not found with id ${params.id}"
//            redirect action:list
//        } else {
//            return [company:company]
//        }
//    }

    /** ACTIONS **/
    // Save/Update/Delete Actions
    def save = {
        def officeCall = new OfficeCall(params.officeCall)
        officeCall.company = Company.get(params.company.id)
        if(!officeCall.hasErrors() && officeCall.save()) {
            flash.message = "OfficeCall ${officeCall} created."
            if (params.returnController) {
                redirect controller:params.returnController, action:params.returnAction, params:[id:officeCall.company.id]
            } else {
                redirect action:list, params:[companyId:officeCall.company.id]
            }
            return
        }
        render view:'create', model:[officeCall:officeCall, returnAction:params.returnAction, returnController:params.returnController]
    }

    def update = {
        def officeCall = OfficeCall.get( params.id )
        if(officeCall) {
            if(params.version) {
                def version = params.version.toLong()
                if(officeCall.version > version) {
                    
                    officeCall.errors.rejectValue("version", "officeCall.optimistic.locking.failure", "Another user has updated this officeCall while you were editing.")
                    render(view:'edit',model:[officeCall:officeCall])
                    return
                }
            }
            officeCall.properties = params
            if(!officeCall.hasErrors() && officeCall.save()) {
                flash.message = "officeCall ${params.id} updated"
                redirect(action:show,id:officeCall.id)
            }
            else {
                render(view:'edit',model:[officeCall:officeCall])
            }
        }
        else {
            flash.message = "officeCall not found with id ${params.id}"
            redirect(action:list)
        }
    }

    /** JSON DATA **/
    def listAsJSON = {
        // Getting the required values and setting up defaults for the default
        // office call list table.
        def sortIndex = params.sidx ?: 'date'
        def sortOrder = params.sord ?: 'desc'
        def maxRows = Integer.valueOf(params.rows)
        def currentPage = Integer.valueOf(params.page) ?: 1
        def rowOffset = currentPage == 1 ? 0 : (currentPage - 1) * maxRows
        def searchValue = params.searchValue
        def officeCalls
        def contact
        def rep
        def company
        def count

        if (params.companyId) {
            company = Company.get(params.companyId)
            if (company) {
                officeCalls = Company.get(params.companyId).officeCalls
            } else {
                flash.message = "There was no company found for the id " + params.companyId
                return
            }
            count = officeCalls.size()
        } else {
            officeCalls = OfficeCalls.createCriteria().list(max:maxRows, offset:rowOffset) {
                // Searching for the criteria in the fields indicated below.
                // Using ilike to perform a case insensitive search.
// Need to develop the query for the office calls.
//                if (searchValue && searchValue.trim().length() > 1) {
//                    or {
//                        ilike("firstName", "%${searchValue}%")
//                        ilike("lastName", "%${searchValue}%")
//                        ilike("phone", "%${searchValue}%")
//                        ilike("email", "%${searchValue}%")
//                    }
//                }

                // Set the order.
                order(sortIndex, sortOrder).ignoreCase()
            }
            count = officeCalls.totalCount
        }

        if (!officeCalls) {
            flash.message = "There were no Office Calls found."
            return
        }

        // Create the cells string to be converted to json later.
        def jsonCells = officeCalls.collect {
            [cell: [
                    it.company.name,
                    it.contact.name,
                    it.rep.person.name,
                    it.type.name,
                    it.date,
                    it.notes
                ],
                id: it.id]
        }

        // Create the rest of the json string to be used.
        def results = [rows:jsonCells, page:currentPage,
                       records:count,
                       total:Math.ceil(count / maxRows)]

        // If the results are null we set the results to "".
        if (!results) {
            results = ""
        }
        render results as JSON
    }
}
